import { Avatar } from "@/components/Avatar";
import { Chat } from "./Chat";
import { useEffect, useState, useRef } from "react";
import { Input, Button, Skeleton, Tooltip, message } from "antd";
import {
  getChatRooms,
  IRoom,
  getRoomDetail,
  RoomDetail,
  getUnreadMessage,
  IUnread,
  clearUnread,
  createPrivateChat,
  createGroupChat,
  searchRoomByIds,
  joinRoom,
  quitRoom,
  destroyRoom,
} from "@/apis/chatroom";
import { getFriends } from "@/apis/friends";
import { IUser } from "@/store/user";
import { getMessageList, IMessage, MessageType } from "@/apis/message";
import { io, Socket } from "socket.io-client";
import { useUserStore } from "@/store/user";
import { SelectUserModal } from "@/components/SelectUserModal";
import { UploadAvatar } from "@/components/uploadAvatar";
import { upload } from "@/utils/upload";
import { Phone } from "@/components/Phone";
import { PhoneStatus } from "@/components/Phone/interface";
import { useCountdown } from "@/hooks/useCoundown";
import WebrtcConnection from "@/utils/WebrtcConnection";

// socket 发送事件类型
// 加入房间
export interface IJoinRoomPayload {
  userId: number;
  roomId: number;
}

// 发送消息
export interface ISendMessagePayload {
  sendUserId: number;
  roomId: number;
  message: ISocketMessage;
}

// 消息结构
export interface ISocketMessage {
  type: MessageType;
  content: string;
}

// 呼叫
export interface ICallPayload {
  roomId: number;
  callerId: number;
  calleeIds: number[];
  isVideoCall: boolean;
}
// 接听
export interface IAcceptCallPayload {
  roomId: number;
  calleeId: number;
}
// 挂断
export interface IHangUpCallPayload {
  roomId: number;
  callerIds: number; // 挂断方ID
  calleeIds: number[]; // 需要通知的ID
}

export interface IOfferPayload {
  callerId: number;
  calleeId: number;
  sdp: RTCSessionDescriptionInit;
}

export interface IAnswerPayload {
  callerId: number;
  calleeId: number;
  sdp: RTCSessionDescriptionInit;
}

export interface ICandidatePayload {
  callerId: number;
  calleeId: number;
  candidate: RTCIceCandidateInit;
}

// socket 响应事件类型
type Reply =
  | {
      type: "sendMessage";
      userId: number;
      message: IMessage;
    }
  | {
      type: "joinRoom";
      userId: number;
    }
  | {
      type: "updateUnreadCount";
      userId: number;
      roomId: number;
    }
  | {
      type: "createRoom";
      roomId: number;
    }
  | {
      type: "destoryRoom";
      roomId: number;
    }
  | {
      type: "call";
      roomId: number;
      callerId: number;
      calleeIds: number[];
      isVideoCall: boolean;
    }
  | {
      type: "acceptCall";
      roomId: number;
      calleeId: number;
    }
  | {
      type: "hangUpCall";
      roomId: number;
      calleeId: number;
      hangUpId: number;
    }
  | {
      type: "offer";
      fromUserId: number;
      offer: RTCSessionDescriptionInit;
    }
  | {
      type: "answer";
      fromUserId: number;
      answer: RTCSessionDescriptionInit;
    }
  | {
      type: "candidate";
      fromUserId: number;
      candidate: RTCIceCandidateInit;
    };
export function Chatroom() {
  const socketRef = useRef<Socket>();
  const { userInfo } = useUserStore();
  const [activeRoomId, setActiveRoomId] = useState<number | null>(null);
  const [activeRoomInfo, setActiveRoomInfo] = useState<RoomDetail | null>(null);

  const [inputText, setInputText] = useState<string>("");
  const [rooms, setRooms] = useState<IRoom[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  // 加载房间
  const searchRoom = async (options: { name: string }) => {
    setIsLoading(true);
    const [success, rooms] = await getChatRooms(options);
    if (success) {
      setRooms(rooms);
    }
    setIsLoading(false);
  };

  // 根据输入筛选房间
  useEffect(() => {
    searchRoom({
      name: inputText,
    });
  }, [inputText]);

  // 发起群聊弹框
  // 选择建群的好友
  const [groupAvatar, setGroupAvatar] = useState<File | string>();
  const [groupName, setGroupName] = useState("");
  const [selectedUserIds, seteSelectedUserId] = useState<number[]>([]);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const addRoom = () => {
    setIsModalOpen(true);
    seteSelectedUserId([]);
    friends.map((friend) => {
      delete friend.disabled;
      return friend;
    });
  };
  const createRoom = async () => {
    // 1. 首先判断选择的好友个数
    if (selectedUserIds.length < 1) {
      return message.info("请选择聊天好友");
    }

    if (selectedUserIds.length === 1) {
      // 创建单聊

      // 1. 查询是否存在该单聊房间
      const [success, room] = await searchRoomByIds({
        memberIds: JSON.stringify(selectedUserIds),
      });
      if (success) {
        if (room.length) {
          // 如果存在单聊，则直接进入
          setActiveRoomId(room[0]);
        } else {
          // 不存在则创建单聊
          const [success, newRoomId] = await createPrivateChat({
            friendId: selectedUserIds[0],
          });
          if (success) {
            // 重新获取房间列表
            searchRoom({
              name: inputText,
            });
            if (newRoomId) {
              setActiveRoomId(newRoomId);
            }
          }
        }
      }
    } else {
      if (!groupName) return message.info("请输入群聊名称");
      let avatarUrl: string | undefined = undefined;
      if (groupAvatar) {
        if (typeof groupAvatar !== "string") {
          // 如果是文件，则上传
          const [success, file] = await upload(groupAvatar);
          if (success) {
            avatarUrl = file.url;
          } else {
            return message.info("上传头像失败");
          }
        } else {
          avatarUrl = groupAvatar;
        }
      }
      // 创建群聊
      const [success, newRoomId] = await createGroupChat({
        name: groupName,
        avatar: avatarUrl,
        friendIds: JSON.stringify(selectedUserIds),
      });
      if (success) {
        setGroupName("");
        setGroupAvatar(undefined);
        // 重新获取房间列表
        searchRoom({
          name: inputText,
        });
        if (newRoomId) {
          setActiveRoomId(newRoomId);
        }
      }
    }

    seteSelectedUserId([]);
    setIsModalOpen(false);
  };
  const handleCancel = () => {
    setIsModalOpen(false);

    // 移除 friends 中所有 disabled 属性
    setFriends((prev) => {
      return prev.map((item) => {
        delete item.disabled;
        return item;
      });
    });
  };

  // 获取好友列表
  const [friends, setFriends] = useState<Array<IUser & { disabled?: boolean }>>(
    []
  );
  useEffect(() => {
    async function getFriendList() {
      const [success, friends] = await getFriends({ name: "" });
      if (success) {
        setFriends(friends);
      }
    }
    getFriendList();

    // 获取未读消息
    getUnredMessage();
  }, []);

  // 切换房间时重新连接
  useEffect(() => {
    if (!userInfo) return;

    // 创建 WebSocket 连接，传递 userId 作为查询参数
    const socket = (socketRef.current = io(import.meta.env.VITE_SERVER_HOST, {
      query: { userId: userInfo.id },
    }));

    socket.on("connect", () => {
      if (!activeRoomId) return;
      // 发送 joinRoom 事件并附带房间和用户信息
      const payload: IJoinRoomPayload = {
        roomId: activeRoomId,
        userId: userInfo.id,
      };
      socket.emit("joinRoom", payload);
    });

    // 处理接收到的消息
    socket.on("message", (reply: Reply) => {
      switch (reply.type) {
        case "sendMessage": // 在线且进入房间的用户才能接收到的事件
          console.log("在线且进入房间");
          appendMessage(reply.message);
          break;
        case "updateUnreadCount": // 在线但不进入房间的用户才能接收到的事件
          console.log("在线但不进入房间");
          getUnredMessage();
          break;
        case "createRoom": // 被拉入房间时主动刷新房间列表
          searchRoom({
            name: inputText,
          });
          break;
        case "call": // 收到通话请求：打开呼叫机
          receivedCall({
            roomId: reply.roomId,
            callerId: reply.callerId,
            calleeIds: reply.calleeIds,
            isVideoCall: reply.isVideoCall,
          });
          break;
        case "acceptCall": // 收到接受通话请求：创建 peer 连接，发送 offer 给对方
          if (reply.calleeId === userInfo.id) return;
          receiveAccept(reply);
          break;
        case "hangUpCall":
          receiveHangUp(reply);
          break;
        case "offer": // 接收 offer：先保存起来，然后生成 answer 发送给对方
          receiveOffer(reply);
          break;
        case "answer": // 接收 answer：设置对方的 SDP
          receiveAnswer(reply);
          break;
        case "candidate":
          receiveCandidate(reply);
          break;
      }
    });

    // 清理连接：在组件卸载或依赖项变化时断开连接
    return () => {
      socket.disconnect();
    };
  }, [activeRoomId, userInfo]); // 将 userInfo 添加到依赖项中

  // 根据房间id获取房间信息以及聊天记录
  const [messageList, setMessageList] = useState<IMessage[]>([]);
  useEffect(() => {
    async function getRoomInfo() {
      if (activeRoomId) {
        // 获取房间成员信息
        const [roomInfoSuccess, roomInfo] = await getRoomDetail(activeRoomId);
        if (roomInfoSuccess) {
          setActiveRoomInfo(roomInfo);
        }

        // 获取聊天记录
        const [messageListSuccess, data] = await getMessageList({
          roomId: activeRoomId,
        });
        if (messageListSuccess) {
          setMessageList(data);
          setTimeout(() => {
            document
              .getElementById("bottom-bar")
              ?.scrollIntoView({ block: "end" });
          });
        }

        // 存在未读消息则清空
        if (unReadMessage.has(activeRoomId)) {
          const unread = unReadMessage.get(activeRoomId);
          if (unread && unread?.unreadCount > 0) {
            await clearUnreadMessage(activeRoomId);
          }
        }
      }
    }
    getRoomInfo();
  }, [activeRoomId]);

  // 追加接收到的消息
  function appendMessage(message: IMessage) {
    setMessageList((prev) => {
      return messageList ? [...prev, message] : [message];
    });
    setTimeout(() => {
      document
        .getElementById("bottom-bar")
        ?.scrollIntoView({ block: "end", behavior: "smooth" });
    }, 200);
  }

  // 添加消息
  function addMessage(message: ISocketMessage) {
    SendMessage(message);
  }

  // 发送消息
  function SendMessage(message: ISocketMessage, isSystem?: boolean) {
    if (!userInfo || !activeRoomId) return;
    const payload: ISendMessagePayload = {
      sendUserId: isSystem ? -1 : userInfo.id,
      roomId: activeRoomId,
      message,
    };

    socketRef.current?.emit("sendMessage", payload);
  }

  // 获取未读信息元数据
  const [unReadMessage, setUnreadMessage] = useState(
    new Map<number, IUnread>()
  );
  async function getUnredMessage() {
    const [success, data] = await getUnreadMessage();
    if (success) {
      const dataMap = new Map(data.map((item) => [item.roomId, item]));
      setUnreadMessage(dataMap);
    }
  }
  async function clearUnreadMessage(roomId: number) {
    const [success] = await clearUnread(roomId);
    if (success) {
      getUnredMessage(); // 清空后重新获取未读信息
    }
  }

  // 添加成员
  const [isAddUserModalOpen, setIsAddUserModalOpen] = useState(false);
  const [selectedAddUserIds, seteSelectedAddUserId] = useState<number[]>([]);
  function addMember(roomInfo: RoomDetail) {
    // 获取房间所有成员ID
    const usersIds = roomInfo.users.map((item) => item.id);
    // 将这些成员设置为不可选
    setFriends((prev) => {
      return prev.map((item) => {
        if (usersIds.includes(item.id)) {
          return { ...item, disabled: true };
        } else {
          return { ...item, disabled: false };
        }
      });
    });
    setIsAddUserModalOpen(true);
  }
  const handleAddUserModalOk = async () => {
    if (!selectedAddUserIds.length) {
      return message.info("请选择要添加的用户");
    }
    if (!activeRoomId) return;
    const [success] = await joinRoom(
      activeRoomId,
      JSON.stringify(selectedAddUserIds)
    );
    if (success) {
      // 更新房间列表信息
      const [successRoomInfo, roomInfo] = await getRoomDetail(activeRoomId);
      if (successRoomInfo) {
        setActiveRoomInfo(roomInfo);
        seteSelectedAddUserId([]);
      }
    }
    setIsAddUserModalOpen(false);
  };
  const handleAddUserModalCancel = () => {
    setIsAddUserModalOpen(false);
  };

  // 删除成员
  const [isRemoveUserModalOpen, setIsRemoveUserModalOpen] = useState(false);
  const [selectedRemoveUserIds, seteSelectedRemoveUserId] = useState<number[]>(
    []
  );
  function removeMember() {
    // 获取房间所有成员ID
    setIsRemoveUserModalOpen(true);
    seteSelectedRemoveUserId([]);
    friends.map((friend) => {
      delete friend.disabled;
      return friend;
    });
  }
  const handleRemoveUserModalOk = async () => {
    if (!selectedRemoveUserIds.length) {
      return message.info("请选择要移除的用户");
    }
    if (!activeRoomId) return;
    const [success] = await quitRoom(
      activeRoomId,
      JSON.stringify(selectedRemoveUserIds)
    );
    if (success) {
      // 更新房间列表信息
      const [successRoomInfo, roomInfo] = await getRoomDetail(activeRoomId);
      if (successRoomInfo) {
        setActiveRoomInfo(roomInfo);
        seteSelectedRemoveUserId([]);

        // 如果移除的是自己或者移除后房间小于2个人则销毁房间
        if (
          (userInfo && selectedRemoveUserIds.includes(userInfo.id)) ||
          roomInfo.users.length < 2
        ) {
          const [success] = await destroyRoom(activeRoomId);
          if (success) {
            message.info("房间已销毁");
            searchRoom({
              name: inputText,
            });
            setActiveRoomId(null);
          }
        }
      }
    }
    setIsRemoveUserModalOpen(false);
  };
  const handleRemoveUserModalCancel = () => {
    setIsRemoveUserModalOpen(false);
  };

  // 视频通话
  const [phoneStatus, setPhoneStatus] = useState<PhoneStatus>(
    PhoneStatus.HangUp
  );
  const [phoneCallerId, setPhoneCallerId] = useState<number>();
  const [phoneCalleeIds, setPhoneCalleeIds] = useState<number[]>([]);
  const [phoneIsVideoCall, setPhoneIsVideoCall] = useState(true);
  const localStreamRef = useRef<MediaStream | null>(null);
  const remoteStreamsRef = useRef<Map<number, MediaStream>>(new Map());
  const peerConnectionsRef = useRef<
    Map<number, InstanceType<typeof WebrtcConnection>>
  >(new Map());
  const { startCountdown, clearCountdown } = useCountdown(); // 倒计时

  //（A）打开呼叫机
  const openCall = (isVideoCall: boolean) => {
    if (activeRoomInfo && userInfo) {
      setPhoneCallerId(userInfo.id);
      setPhoneCalleeIds([]);
      setPhoneIsVideoCall(isVideoCall);
      setPhoneStatus(PhoneStatus.Open);

      if (activeRoomInfo.chatType === "Private") {
        const otherUserId = activeRoomInfo.users.filter(
          (user) => user.id !== userInfo.id
        )[0].id;
        sendCall([otherUserId], isVideoCall);
      }
    }
  };

  // （A）呼叫用户（B、C）
  const sendCall = async (calleeIds: number[], isVideoCall?: boolean) => {
    if (activeRoomId && userInfo) {
      const localStream = await createLocalStream(
        isVideoCall || phoneIsVideoCall
      ); // 创建本地流
      if (!localStream) {
        message.error("获取本地流失败，请检查摄像头麦克风权限或设备占用");
        return;
      }
      localStreamRef.current = localStream; // 保存本地流
      setPhoneCalleeIds(calleeIds);
      setPhoneStatus(PhoneStatus.Calling);

      // 发送呼叫请求
      const payload: ICallPayload = {
        roomId: activeRoomId,
        callerId: userInfo.id,
        calleeIds: calleeIds,
        isVideoCall: isVideoCall || phoneIsVideoCall,
      };
      socketRef.current?.emit("call", payload);
    }
    // 倒计时完成后，没有接听则帮挂
    startCountdown(15, () => {
      if (calleeIds.length > 0) {
        const unAnswerIds = calleeIds.filter(
          (id) => !peerConnectionsRef.current.get(id)
        );
        console.log("帮挂启动", unAnswerIds);
        unAnswerIds.forEach((hangUpId) => {
          socketRef.current?.emit("hangUpCall", {
            roomId: activeRoomId,
            hangUpId: hangUpId,
            callerId: phoneCallerId,
            calleeIds: calleeIds.filter((id) => id !== hangUpId),
          });
        });
      }
    });
  };

  useEffect(() => {
    console.log("本地流变化", localStreamRef.current);
  }, [localStreamRef.current]);

  // socket事件：（B、C）收到呼叫请求
  const receivedCall = async (option: {
    roomId: number;
    callerId: number;
    isVideoCall: boolean;
    calleeIds: number[];
  }) => {
    const { roomId, callerId, isVideoCall, calleeIds } = option;
    const localStream = await createLocalStream(isVideoCall); // 创建本地流
    if (!localStream) {
      message.error("获取本地流失败，请检查摄像头麦克风权限或设备占用");
      return;
    }
    localStreamRef.current = localStream;
    console.log("收到呼叫请求，创建本地流", localStreamRef.current);

    setActiveRoomId(roomId);
    setPhoneCallerId(callerId);
    setPhoneCalleeIds(calleeIds);
    setPhoneIsVideoCall(isVideoCall);
    setPhoneStatus(PhoneStatus.Calling);
  };

  // （B）点击接听
  const onAccept = () => {
    if (!userInfo || !activeRoomId) return;
    clearCountdown(); // 清除倒计时
    setPhoneStatus(PhoneStatus.Chating);

    // 发送 offer
    const payload: IAcceptCallPayload = {
      roomId: activeRoomId,
      calleeId: userInfo.id, // 发送自身
    };
    socketRef.current?.emit("acceptCall", payload);
  };

  // （A）socket事件：有用户接听，创建发送 offer
  const receiveAccept = (reply: Extract<Reply, { type: "acceptCall" }>) => {
    if (!userInfo) return;
    const { calleeId } = reply;

    setPhoneStatus(PhoneStatus.Chating);
    const connection = getConnection(calleeId);
    connection.createAndSetLocalOffer((sdp) => {
      const payload = {
        fromUserId: userInfo.id,
        toUserId: calleeId,
        offer: sdp,
      };
      socketRef.current?.emit("offer", payload);
    });
  };

  // （B）socket事件：收到 offer
  const receiveOffer = (payload: Extract<Reply, { type: "offer" }>) => {
    if (!userInfo) return;
    const { fromUserId, offer } = payload;
    const connection = getConnection(fromUserId); // 多啦A梦
    connection.setRemoteDescription(offer);
    connection.createAndSetLocalAnswer((sdp) => {
      socketRef.current?.emit("answer", {
        toUserId: fromUserId,
        fromUserId: userInfo.id,
        answer: sdp,
      });
    });
  };

  // （A）socket 事件：收到 Answer
  const receiveAnswer = (payload: Extract<Reply, { type: "answer" }>) => {
    if (!userInfo) return;
    const { fromUserId, answer } = payload;
    const connection = getConnection(fromUserId);
    connection.setRemoteDescription(answer);
  };

  // （A、B）socket事件：收到 ICE
  const receiveCandidate = (payload: Extract<Reply, { type: "candidate" }>) => {
    if (!userInfo) return;
    const { fromUserId, candidate } = payload;
    const connection = getConnection(fromUserId);
    connection.setRemoteCandidate(candidate);
  };

  useEffect(() => {
    console.log("手机状态", phoneStatus);
  }, [phoneStatus]);

  // 挂断自己
  const onHangUp = () => {
    if (!userInfo) return;
    clearCountdown(); // 清除倒计时
    // 关闭所有连接
    for (const [, connection] of peerConnectionsRef.current) {
      connection.close();
    }
    peerConnectionsRef.current.clear(); // 清除所有连接
    remoteStreamsRef.current.clear(); // 清除所有远端流
    clearLocalStream(); // 销毁本地流
    setPhoneStatus(PhoneStatus.HangUp);
    console.log("自挂", phoneCallerId, phoneCalleeIds);

    socketRef.current?.emit("hangUpCall", {
      roomId: activeRoomId,
      hangUpId: userInfo.id,
      callerId: phoneCallerId,
      calleeIds: phoneCalleeIds,
    });
  };

  // socket事件：挂断-说明有人结束了通话，需要把这个人从自己列表中移除
  const receiveHangUp = (payload: Extract<Reply, { type: "hangUpCall" }>) => {
    if (!userInfo) return;

    const { hangUpId } = payload;

    if (hangUpId) {
      // 移除用户头像
      setPhoneCalleeIds((prev) => {
        return prev.filter((userId) => userId !== hangUpId);
      });
      // 如果存在该连接，则关闭
      const connection = peerConnectionsRef.current.get(hangUpId);
      if (connection) {
        connection.close();
        // 移除连接
        peerConnectionsRef.current.delete(hangUpId);
        remoteStreamsRef.current.delete(hangUpId);
      }

      // 如果所有连接都关闭了，则设置状态为挂断
      if (
        peerConnectionsRef.current.size === 0 &&
        remoteStreamsRef.current.size === 0 &&
        phoneCalleeIds.length === 0
      ) {
        clearLocalStream();
        setPhoneStatus(PhoneStatus.HangUp);
      }
    }
  };

  // 创建本地流
  const createLocalStream = async (isVideoCall: boolean) => {
    try {
      console.log("创建本地流");
      return await navigator.mediaDevices.getUserMedia({
        video: isVideoCall,
        audio: {
          echoCancellation: true, // 启用回声消除
        },
      });
    } catch (error) {
      console.error("本地流获取失败", error);
      throw new Error("本地流获取失败");
      return null;
    }
  };

  // 销毁本地流
  const clearLocalStream = async () => {
    if (localStreamRef.current) {
      localStreamRef.current.getTracks().forEach((track) => {
        track.stop();
      });
      localStreamRef.current = null;
    }
  };

  const addRemoteStream = (userId: number, event: RTCTrackEvent) => {
    console.log("收到远端流", userId, event.streams[0]);
    remoteStreamsRef.current.set(userId, event.streams[0]);
  };

  const getConnection = (userId: number) => {
    let connection = peerConnectionsRef.current.get(userId);

    if (!connection) {
      connection = new WebrtcConnection();
      connection.create(
        (candidate: RTCIceCandidate) => {
          if (userInfo) {
            socketRef.current?.emit("candidate", {
              fromUserId: userInfo.id,
              toUserId: userId,
              candidate,
            });
          }
        },
        (event: RTCTrackEvent) => addRemoteStream(userId, event)
      ); // 接收 3 个函数作为参数，这三个函数会分别在收到流时、删除流时、turn 服务器返回的 candidate 时触发
      peerConnectionsRef.current.set(userId, connection);

      if (localStreamRef.current) {
        console.log("本地流存在", localStreamRef.current);
        connection.addTrack(localStreamRef.current);
      } else {
        console.log("本地流不存在");
      }
    }
    return connection;
  };

  return (
    <div className="flex p-4 w-full">
      <div className="flex flex-col w-[280px]">
        <h3 className="h-[60px] text-xl font-bold text-white">聊天室</h3>
        <div className="flex justify-between items-center gap-2">
          <Input
            size="large"
            placeholder="搜索房间"
            onChange={(e) => setInputText(e.target.value)}
          />
          <Tooltip title="发起聊天">
            <Button
              size="large"
              type="primary"
              className="text-xl"
              onClick={addRoom}
            >
              <span className="iconfont icon-tianjia !text-[20px]"></span>
            </Button>
          </Tooltip>
          <SelectUserModal
            title="选择好友开始聊天"
            open={isModalOpen}
            users={friends}
            selectValues={selectedUserIds}
            selectChange={seteSelectedUserId}
            onCancel={handleCancel}
            onOk={createRoom}
          >
            {selectedUserIds.length > 1 && (
              <div>
                <UploadAvatar onChange={setGroupAvatar} />
                <Input
                  value={groupName}
                  onChange={(e) => setGroupName(e.target.value)}
                  placeholder="输入群聊名称"
                />
              </div>
            )}
          </SelectUserModal>
          <SelectUserModal
            title="添加好友"
            open={isAddUserModalOpen}
            users={friends}
            selectValues={selectedAddUserIds}
            selectChange={seteSelectedAddUserId}
            onCancel={handleAddUserModalCancel}
            onOk={handleAddUserModalOk}
          ></SelectUserModal>
          <SelectUserModal
            title="移除好友"
            open={isRemoveUserModalOpen}
            users={activeRoomInfo?.users}
            selectValues={selectedRemoveUserIds}
            selectChange={seteSelectedRemoveUserId}
            onCancel={handleRemoveUserModalCancel}
            onOk={handleRemoveUserModalOk}
          ></SelectUserModal>
          {activeRoomInfo && (
            <Phone
              room={activeRoomInfo}
              type={phoneIsVideoCall ? "video" : "audio"}
              status={phoneStatus}
              callerId={phoneCallerId}
              calleeIds={phoneCalleeIds}
              onStatus={setPhoneStatus}
              onCall={sendCall}
              onAccept={onAccept}
              onHangUp={onHangUp}
              localStream={localStreamRef.current}
              remoteStreamRefs={remoteStreamsRef}
            />
          )}
        </div>
        <div className="flex-1 mt-8 overflow-y-hidden scrollbar-custom hover:overflow-y-auto">
          <ul>
            {isLoading
              ? // Skeleton 占位符效果
                Array.from({ length: 3 }).map((_, index) => (
                  <Skeleton key={index} active avatar />
                ))
              : // 数据加载完成后渲染真实数据
                rooms.map((item, index) => (
                  <li
                    key={index}
                    className={`w-[95%] flex items-center p-3 rounded-lg mb-4 bg-slate-500/10 text-white gap-2 cursor-pointer
            ${
              activeRoomId === item.id
                ? "!bg-[#1d90f5] transition duration-300 shadow-[3px_2px_10px_0px_rgb(0,136,255)]"
                : "hover:bg-slate-500/20"
            }`}
                    onClick={() => setActiveRoomId(item.id)}
                  >
                    <Avatar
                      name={item.name}
                      src={item?.avatar}
                      unRead={unReadMessage.get(item.id)?.unreadCount}
                      desc={
                        unReadMessage.get(item.id)?.lastUnreadMessage?.content
                      }
                    />
                  </li>
                ))}
          </ul>
        </div>
      </div>
      <div className="flex-1 min-w-[400px] h-full px-4 flex flex-col ">
        {activeRoomId && activeRoomInfo ? (
          <Chat
            messages={messageList}
            roomInfo={activeRoomInfo}
            addMessage={addMessage}
            addMember={addMember}
            removeMember={removeMember}
            call={openCall}
            isOpen={phoneStatus !== PhoneStatus.HangUp}
            isVideo={phoneIsVideoCall}
          >
            <div id="bottom-bar"></div>
          </Chat>
        ) : (
          <span className="iconfont icon-snapchat !text-[300px] text-gray-300 h-full flex justify-center items-center"></span>
        )}
      </div>
    </div>
  );
}
